from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from config.database import get_db
from service.user_service import UserService
from pydantic import BaseModel, Field
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from utils.response import ResponseModel
from utils.exceptions import AuthException, ParamException
from typing import Optional, Any

router = APIRouter(
    tags=["用户管理"],
    responses={
        404: {"description": "未找到"},
        401: {"description": "未授权"},
        403: {"description": "禁止访问"}
    }
)
security = HTTPBearer()

class UserCreate(BaseModel):
    """用户创建/登录请求模型"""
    username: str = Field(
        ...,
        title="用户名",
        description="用户名，长度在3-50个字符之间",
        min_length=3,
        max_length=50,
        example="zhangsan"
    )
    password: str = Field(
        ...,
        title="密码",
        description="密码，长度在6-100个字符之间",
        min_length=6,
        max_length=100,
        example="123456"
    )

class TokenData(BaseModel):
    """令牌数据模型"""
    access_token: str = Field(..., title="访问令牌", description="用于身份验证的JWT令牌")
    token_type: str = Field("bearer", title="令牌类型", description="令牌类型，固定为bearer")

class ApiResponse(BaseModel):
    """API通用响应模型"""
    code: int = Field(200, title="状态码", description="接口调用状态码，200表示成功")
    message: str = Field("success", title="响应消息", description="接口调用结果说明")
    data: Optional[Any] = Field(None, title="响应数据", description="接口返回的具体数据")

class TokenApiResponse(ApiResponse):
    """令牌响应模型"""
    data: TokenData

class MessageApiResponse(ApiResponse):
    """消息响应模型"""
    message: str = Field(..., title="响应消息", description="操作结果说明")
    data: None = None

@router.post("/register", summary="用户注册", description="""
注册新用户账号。

注册成功后会自动登录，返回访问令牌。
""", response_model=TokenApiResponse)
async def register(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    db_user = UserService.create_user(db, user.username, user.password)
    if not db_user:
        raise ParamException("用户名已被注册")
    
    token = UserService.create_token(db_user.id)
    return TokenApiResponse(
        data=TokenData(
            access_token=token,
            token_type="bearer"
        )
    )

@router.post("/login", summary="用户登录", description="""
用户登录并获取访问令牌。

使用用户名和密码进行身份验证，成功后返回访问令牌。
""", response_model=TokenApiResponse)
async def login(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    db_user = UserService.authenticate_user(db, user.username, user.password)
    if not db_user:
        raise AuthException("用户名或密码错误")
    
    token = UserService.create_token(db_user.id)
    return TokenApiResponse(
        data=TokenData(
            access_token=token,
            token_type="bearer"
        )
    )

@router.post("/logout", summary="用户登出", description="""
退出登录，使当前的访问令牌失效。

需要在请求头中携带有效的访问令牌。
""", response_model=MessageApiResponse)
async def logout(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    UserService.logout(credentials.credentials)
    return MessageApiResponse(message="退出登录成功") 